package cn.t.facade.user;


import cn.t.converter.user.CostCenterDTOConverter;
import cn.t.core.exception.BizException;
import cn.t.core.facade.FacadeImpl;
import cn.t.core.mode.PageInfoDTO;
import cn.t.core.mode.PageQueryDTO;
import cn.t.core.mode.SortedParamDTO;
import cn.t.dto.user.CostCenterDTO;
import cn.t.core.enums.base.CommonError;
import cn.t.model.user.CostCenterDO;
import cn.t.model.user.UserQueryDO;
import cn.t.service.user.CostCenterService;
import cn.t.service.user.UserQueryService;
import cn.t.vo.andriod.AndroidCostCenterVO;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 场景信息表服务编排
 *
 * @author l
 */
@Slf4j
@Service
@AllArgsConstructor
public class CostCenterFacade extends FacadeImpl<CostCenterDTO, CostCenterDO, CostCenterDTOConverter, CostCenterService> {

    @Override
    public boolean add(CostCenterDTO dto) {
        if (dto != null && StringUtils.isNoneBlank(dto.getCostCenterCode())) {
            List<CostCenterDO> costCenterDOList = service.findByCostCenterCode(dto.getFirmId(), dto.getCostCenterCode());
            if (!CollectionUtils.isEmpty(costCenterDOList)) {
                String errorMessage = String.format("存在相同成本中心编码。costCenterCode=%s ", dto.getCostCenterCode());
                log.error(errorMessage);
                throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
            }
        }

        if (dto != null && StringUtils.isNoneBlank(dto.getCostCenterName())) {
            List<CostCenterDO> costCenterDOList = service.findByName(dto.getFirmId(), dto.getCostCenterName());
            if (!CollectionUtils.isEmpty(costCenterDOList)) {
                String errorMessage = String.format("存在相同成本中心名称。costCenterName=%s ", dto.getCostCenterName());
                log.error(errorMessage);
                throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
            }
        }
        return service.add(converter.dto2Model(dto));
    }

    @Override
    public boolean update(CostCenterDTO dto) {
        if (dto == null || dto.getId() == null) {
            String errorMessage = "不存在成本中心。";
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        CostCenterDO costCenterDO = service.findById(dto.getId());
        if (costCenterDO == null) {
            String errorMessage = String.format("不存在成本中心。id=%s ", dto.getId());
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        if (StringUtils.isNoneBlank(dto.getCostCenterCode())) {
            List<CostCenterDO> costCenterDOList = service.findByCostCenterCode(dto.getFirmId(), dto.getCostCenterCode());
            if (!CollectionUtils.isEmpty(costCenterDOList)) {
                for (CostCenterDO tmp : costCenterDOList) {
                    if (!tmp.getId().equals(dto.getId())) {
                        String errorMessage = String.format("存在相同成本中心编码。costCenterCode=%s ", dto.getCostCenterCode());
                        log.error(errorMessage);
                        throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
                    }
                }

            }
        }

        if (StringUtils.isNoneBlank(dto.getCostCenterName())) {
            List<CostCenterDO> costCenterDOList = service.findByName(dto.getFirmId(), dto.getCostCenterName());
            if (!CollectionUtils.isEmpty(costCenterDOList)) {
                for (CostCenterDO tmp : costCenterDOList) {
                    if (!tmp.getId().equals(dto.getId())) {
                        String errorMessage = String.format("存在相同成本中心名称。costCenterName=%s ", dto.getCostCenterName());
                        log.error(errorMessage);
                        throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
                    }
                }
            }
        }

        if (costCenterDO.getFirmId() != null && !costCenterDO.getFirmId().equals(dto.getFirmId())) {
            List<UserQueryDO> tmp = userQueryService.findByCostCenterId(costCenterDO.getId());
            if (!CollectionUtils.isEmpty(tmp)) {
                String errorMessage = String.format("指定的成本中心已绑定用户，不可以修改归属企业。firmId=%s ", dto.getFirmId());
                log.error(errorMessage);
                throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
            }
        }

        boolean result = service.update(converter.dto2Model(dto));
        userQueryFacade.updateByCostCenterId(dto.getId());
        return result;
    }

    @Override
    public boolean remove(Long id) {
        List<UserQueryDO> userQueryList = userQueryService.findByCostCenterId(id);
        if (!CollectionUtils.isEmpty(userQueryList)) {
            String errorMessage = String.format("指定的成本中心已绑定用户，不可删除。costCenterId=%s ", id);
            log.error(errorMessage);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, errorMessage);
        }

        boolean result = service.removeById(id);
        userQueryFacade.updateByCostCenterId(id);
        return result;
    }


    public List<CostCenterDTO> findByFirm(List<Long> firmIds) {

        List<CostCenterDO> list = service.findByFirm(firmIds);

        if (CollectionUtils.isEmpty(list)) {
            return null;
        }

        return list.stream().map(converter::model2Dto).collect(Collectors.toList());
    }


    public Map<Long, CostCenterDO> getCostCenterList(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)){
            return Maps.newHashMap();
        }
        return service.getCostCenterList(ids).stream().collect(Collectors.toMap(CostCenterDO::getId, Function.identity()));
    }

    public PageInfoDTO<CostCenterDTO> entCostCenterPage(PageQueryDTO<CostCenterDTO> queryDTO) {
        SortedParamDTO sortedParamDTO = queryDTO.getSortParam();
        List<CostCenterDTO> list = this.queryList(queryDTO.getParam(), queryDTO.getStart(), queryDTO.getPageSize(), sortedParamDTO.getField(), sortedParamDTO.getDirection());
        if (CollectionUtils.isEmpty(list)) {
            return new PageInfoDTO<>(queryDTO.getPageNo(), queryDTO.getPageSize(), 0L, null);
        } else {
            long total = queryDTO.getTotal();
            if (queryDTO.isNotNeedPageQuery()) {
                total = this.count(queryDTO.getParam());
            }

            return new PageInfoDTO<>(queryDTO.getPageNo(), queryDTO.getPageSize(), total, list);
        }
    }

    @Autowired
    private UserQueryFacade userQueryFacade;

    @Autowired
    private UserQueryService userQueryService;


    public List<AndroidCostCenterVO> findByFirmId(Long firmId) {
        List<CostCenterDTO> list = findByFirm(Arrays.asList(firmId));
        return converter.dto2Vo(list);
    }

    public List<CostCenterDTO> findCostCenter(Long firmId) {

        List<CostCenterDO> costCenterDOS = this.service.findByCostCenterCode(firmId, null);
        return costCenterDOS.stream().map(converter::model2Dto).collect(Collectors.toList());
    }
}

